package cn.wolfcode.luowowo.controller;

import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.domain.Travel;
import cn.wolfcode.luowowo.domain.UserInfo;
import cn.wolfcode.luowowo.search.domain.DestinationEs;
import cn.wolfcode.luowowo.search.domain.StrategyEs;
import cn.wolfcode.luowowo.search.domain.TravelEs;
import cn.wolfcode.luowowo.search.domain.UserInfoEs;
import cn.wolfcode.luowowo.search.query.SearchQueryObject;
import cn.wolfcode.luowowo.search.service.ISearchService;
import cn.wolfcode.luowowo.search.vo.SearchResultVO;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.IStrategyService;
import cn.wolfcode.luowowo.service.ITravelService;
import cn.wolfcode.luowowo.service.IUserInfoService;
import cn.wolfcode.luowowo.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.naming.directory.SearchResult;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 全部/ 目的地 /攻略/游记/找人(搜索查询)
 */
@RestController
public class SearchController {


    @Autowired
    private IDestinationService destinationService;
    @Autowired
    private ITravelService travelService;
    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private IStrategyService strategyService;
    @Autowired
    private ISearchService searchService;

    @GetMapping("/q")
    public Object search(SearchQueryObject qo) throws UnsupportedEncodingException {
        // 页面搜索时乱码解决方案(url传入中文时,会自动将中文进行编码,此时需要解码)
        String code = URLDecoder.decode(qo.getKeyword(), "UTF-8");
        qo.setKeyword(code);

        switch(qo.getType()){
            case SearchQueryObject.TYPE_DEST:
                return searchDest(qo);
            case SearchQueryObject.TYPE_STRATEGY:
                return searchStrategy(qo);
            case SearchQueryObject.TYPE_TRAVEL:
                return searchTravel(qo);
            case SearchQueryObject.TYPE_USER:
                return searchUser(qo);
                default:
                    return searchAll(qo);
        }

    }

    // 精准搜索(目的地)目的地搜索(分析完目的地之后,他还是精确查询,
    // 因为要显示目的列表的同时还要显示用户和游记的,所以要用mongodb去查询)
    private Object searchDest(SearchQueryObject qo) {
        // 输入关键词是精确查询输入的地区
        Destination dest = destinationService.queryName(qo.getKeyword());
        // 如果找到，显示该目的地下所有攻略， 游记， 用户
        // 返回1.result(users  strategys travel total)  2.dest 3.qo前端页面要的三个参数
        SearchResultVO vo = new SearchResultVO();
        if (dest != null) {
            // 攻略
            List<Strategy> sts = strategyService.queryByDestName(qo.getKeyword());
            vo.setStrategys(sts);
            // 游记
            List<Travel> ts = travelService.queryByDestName(qo.getKeyword());
            vo.setTravels(ts);
            // 用户
            List<UserInfo> us = userInfoService.queryByCity(qo.getKeyword());
            vo.setUsers(us);
            //  total总数
            long total = ts.size() + sts.size() + us.size();
            vo.setTotal(total);
        }
        Map<String,Object> map =  new HashMap<>();
        map.put("result",vo);
        map.put("dest",dest);
        map.put("qo",qo);

        return JsonResult.success(map);
    }

    // (高亮)攻略搜索全文模糊  ----->有bug
    private Object searchStrategy(SearchQueryObject qo) {
        System.out.println("--------------Strategy----------");
        // 通过页面的关键词全文搜索,结果需要高亮显示
        Page<Strategy> page = searchService.searchWithHighlight(StrategyEs.INDEX_NAME, StrategyEs.TYPE_NAME,
                Strategy.class, qo,"title","subTitle","summary");

        Map<String,Object> map =  new HashMap<>();
        map.put("page",page);
        map.put("qo",qo);
        return JsonResult.success(map);
    }

    // 游记搜索
    private Object searchTravel(SearchQueryObject qo) {
        // 通过页面的关键词全文搜索,结果需要高亮显示
        Page<Travel> page = searchService.searchWithHighlight(TravelEs.INDEX_NAME, TravelEs.TYPE_NAME,
                Travel.class, qo,"title", "summary");

        Map<String,Object> map =  new HashMap<>();
        map.put("page",page);
        map.put("qo",qo);
        return JsonResult.success(map);
    }


    // 用户搜索
    private Object searchUser(SearchQueryObject qo) {
        // 通过页面的关键词全文搜索,结果需要高亮显示
        Page<UserInfo> page = searchService.searchWithHighlight(UserInfoEs.INDEX_NAME, UserInfoEs.TYPE_NAME,
                UserInfo.class, qo,"info", "city");

        Map<String,Object> map =  new HashMap<>();
        map.put("page",page);
        map.put("qo",qo);
        return JsonResult.success(map);
    }

    // 全部搜索
    private Object searchAll(SearchQueryObject qo) {

        SearchResultVO vo = new SearchResultVO();
        long total = 0L; //搜索结果总条数
        //
        Page<Strategy> sts = searchService.searchWithHighlight(StrategyEs.INDEX_NAME, StrategyEs.TYPE_NAME,
                Strategy.class, qo,"title","subTitle","summary");
        vo.setStrategys(sts.getContent());
        total += sts.getTotalElements();//攻略分页的总条数

        Page<UserInfo> us = searchService.searchWithHighlight(UserInfoEs.INDEX_NAME, UserInfoEs.TYPE_NAME,
                UserInfo.class, qo,"info", "city");
        vo.setUsers(us.getContent());
        total += us.getTotalElements();

        Page<Travel> ts = searchService.searchWithHighlight(TravelEs.INDEX_NAME, TravelEs.TYPE_NAME,
                Travel.class, qo,"title", "summary");
        vo.setTravels(ts.getContent());
        total += ts.getTotalElements();

        Page<Destination> ds = searchService.searchWithHighlight(DestinationEs.INDEX_NAME, DestinationEs.TYPE_NAME,
                Destination.class, qo,"name", "info");
        vo.setDests(ds.getContent());
        total += ds.getTotalElements();

        vo.setTotal(total);

        Map<String,Object> map =  new HashMap<>();
        map.put("result",vo);
        map.put("qo",qo);
        return JsonResult.success(map);
    }
}
